//
// Created by 吴喆 on 2020/4/8.
//

#include "FTFont.h"
#include "../util/Console.h"
#include "CharacterNotFoundException.h"

FTFont::FTFont(std::string &filePath) {
    init(filePath);
}

FTFont::~FTFont() {
    FT_Done_Face(face);
    FT_Done_FreeType(ft);
}

void FTFont::init(std::string &filePath) {
    Font::init(filePath);
    if (FT_Init_FreeType(&ft)) {
        Console::ERR("ERROR::FREETYPE: Could not init FreeType Library");
        return;
    }

    if (FT_New_Face(ft, filePath.data(), 0, &face)) {
        Console::ERR("ERROR::FREETYPE: Failed to load font \"" + filePath + "\"");
        return;
    }
    FT_Set_Pixel_Sizes(face, 0, 80);
    Console::INFO("INIT FONT:\"" + filePath + "\" SUCCESSFULLY");

}

Character *FTFont::initCharacter(wchar_t character) {
    // Load character glyph
    if (FT_Load_Char(face, character, FT_LOAD_RENDER)) {
        Console::ERR("ERROR::FREETYTPE: Failed to load Glyph");
        throw CharacterNotFoundException();
    }
    FT_Select_Charmap(face, FT_ENCODING_UNICODE);


    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    // Generate texture
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(
            GL_TEXTURE_2D,
            0,
            GL_RED,
            face->glyph->bitmap.width,
            face->glyph->bitmap.rows,
            0,
            GL_RED,
            GL_UNSIGNED_BYTE,
            face->glyph->bitmap.buffer
    );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    // Now store character for later use
    Texture2D texture2D;
    texture2D.id = texture;
    auto *ch = new Character{
            texture2D,
            glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
            glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
            static_cast<unsigned int>(face->glyph->advance.x)
    };
    return ch;
}

FTFont::FTFont(const char *filePath) {
    std::string f(filePath);
    new(this) FTFont(f);
}



